<template>
	<view class="shadow" :class="!show?'':'shadow-show'" :style="{backgroundColor:show?maskBg:'rgba(0,0,0,0)'}"
		@tap="tapMask">
		<view class="popups" :class="[theme]" :style="{top: popupsTop ,left: popupsLeft,flexDirection:direction}">
			<text :class="dynPlace" :style="{width:'0px',height:'0px'}" v-if="triangle"></text>
			<view v-for="(item,index) in popData" :key="index" @tap.stop="tapItem(item)" class="itemChild view"
				:class="[direction=='row'?'solid-right':'solid-bottom',item.disabled?'disabledColor':'']">
				<u-icon size="35" :name="item.icon" v-if="item.icon"></u-icon><span class="title">{{item.title}}</span>
			</view>
			<slot></slot>
		</view>
	</view>
</template>

<script>
	export default {
		props: {
			maskBg: {
				type: String,
				default: "rgba(0,0,0,0)",
			},
			placement: {
				type: String,
				default: "default", //default top-start top-end bottom-start bottom-end
			},
			direction: {
				type: String,
				default: "column", //column row
			},
			x: {
				type: Number,
				default: 0,
			},
			y: {
				type: Number,
				default: 0,
			},
			value: {
				type: Boolean,
				default: false,
			},
			popData: {
				type: Array,
				default: () => [],
			},
			theme: {
				type: String,
				default: "light", //light dark
			},
			dynamic: {
				type: Boolean,
				default: false,
			},
			gap: {
				type: Number,
				default: 20,
			},
			triangle: {
				type: Boolean,
				default: true,
			},
		},
		data() {
			return {
				popupsTop: "0rpx",
				popupsLeft: "0rpx",
				show: false,
				dynPlace: "",
			};
		},
		mounted() {
			this.popupsPosition();
		},
		methods: {
			tapMask() {
				this.$emit("input", !this.value);
			},
			tapItem(item) {
				if (item.disabled) return;
				this.$emit("tapPopup", item);
				this.$emit("input", !this.value);
			},
			getStatusBar() {
				let promise = new Promise((resolve, reject) => {
					uni.getSystemInfo({
						success: function(e) {
							let customBar;
							// #ifdef H5

							customBar = e.statusBarHeight + e.windowTop;

							// #endif
							resolve(customBar);
						},
					});
				});
				return promise;
			},
			async popupsPosition() {
				let statusBar = await this.getStatusBar();
				let promise = new Promise((resolve, reject) => {
					let popupsDom = uni.createSelectorQuery().in(this).select(".popups");
					popupsDom
						.fields({
								size: true,
							},
							(data) => {
								let width = data.width;
								let height = data.height;



								let y = this.dynamic ?
									this.dynamicGetY(this.y, this.gap) :
									this.transformRpx(this.y);

								let x = this.dynamic ?
									this.dynamicGetX(this.x, this.gap) :
									this.transformRpx(this.x);

								// #ifdef H5
								y = this.dynamic ?
									this.y + statusBar :
									this.transformRpx(this.y + statusBar);
								// #endif

								this.dynPlace =
									this.placement == "default" ?
									this.getPlacement(x, y) :
									this.placement;

								switch (this.dynPlace) {
									case "top-start":
										this.popupsTop = `${y + 9}rpx`;
										this.popupsLeft = `${x - 15}rpx`;
										break;
									case "top-end":
										this.popupsTop = `${y + 9}rpx`;
										this.popupsLeft = `${x + 15 - width}rpx`;
										break;
									case "bottom-start":
										this.popupsTop = `${y - 18 - height}rpx`;
										this.popupsLeft = `${x - 15}rpx`;
										break;
									case "bottom-end":
										this.popupsTop = `${y - 9 - height}rpx`;
										this.popupsLeft = `${x + 15 - width}rpx`;
										break;
								}
								resolve();
							}
						)
						.exec();
				});
				return promise;
			},
			getPlacement(x, y) {
				let width = uni.getSystemInfoSync().windowWidth;
				let height = uni.getSystemInfoSync().windowHeight;
				if (x > width / 2 && y > height / 2) {
					return "bottom-end";
				} else if (x < width / 2 && y < height / 2) {
					return "top-start";
				} else if (x > width / 2 && y < height / 2) {
					return "top-end";
				} else if (x < width / 2 && y > height / 2) {
					return "bottom-start";
				} else if (x > width / 2) {
					return "top-end";
				} else {
					return "top-start";
				}
			},
			dynamicGetY(y, gap) {
				let height = uni.getSystemInfoSync().windowHeight;
				y = y < gap ? gap : y;
				y = height - y < gap ? height - gap : y;

				return y;
			},
			dynamicGetX(x, gap) {
				let width = uni.getSystemInfoSync().windowWidth;
				x = x < gap ? gap : x;
				x = width - x < gap ? width - gap : x;
				return x;
			},
			transformRpx(params) {
				return (params * uni.getSystemInfoSync().screenWidth) / 375;
			},
		},
		watch: {
			value: {
				immediate: true,
				handler: async function(newVal, oldVal) {
					if (newVal) await this.popupsPosition();
					this.show = newVal;
				},
			},
			placement: {
				immediate: true,
				handler(newVal, oldVal) {
					this.dynPlace = newVal;
				},
			},
		},
	};
</script>

<style lang="scss" scoped>
	.title {
		margin-left: 20rpx;
	}

	.shadow {
		position: fixed;
		top: 0;
		right: 0;
		bottom: 0;
		left: 0;
		height: 100%;
		z-index: 9999;
		transition: background 0.3s ease-in-out;
		visibility: hidden;

		&.shadow-show {
			visibility: visible;
		}
	}

	.popups {
		position: absolute;
		padding: 20rpx;
		border-radius: 5px;
		display: flex;

		.view {
			display: flex;
			align-items: center;
			padding: 15rpx 10rpx;
			font-size: 25rpx;
		}

		.image {
			display: inline-block;
			vertical-align: middle;
			width: 40rpx;
			height: 40rpx;
			margin-right: 20rpx;
		}
	}

	.dark {
		background-color: #4c4c4c;
		color: #fff;

		.top-start:after {
			content: "";
			position: absolute;
			top: -18rpx;
			left: 10rpx;
			border-width: 0 20rpx 20rpx;
			border-style: solid;
			border-color: transparent transparent #4c4c4c;
		}

		.top-end:after {
			content: "";
			position: absolute;
			top: -18rpx;
			right: 10rpx;
			border-width: 0 20rpx 20rpx;
			border-style: solid;
			border-color: transparent transparent #4c4c4c;
		}

		.bottom-start:after {
			content: "";
			position: absolute;
			bottom: -18rpx;
			left: 10rpx;
			border-width: 20rpx 20rpx 0;
			border-style: solid;
			border-color: #4c4c4c transparent transparent;
		}

		.bottom-end:after {
			content: "";
			position: absolute;
			bottom: -18rpx;
			right: 10rpx;
			border-width: 20rpx 20rpx 0;
			border-style: solid;
			border-color: #4c4c4c transparent transparent;
		}

		.disabledColor {
			color: #c5c8ce;
		}
	}

	.light {
		color: #515a6e;
		box-shadow: 0upx 0upx 30upx rgba(0, 0, 0, 0.2);
		background: #fff;

		.top-start:after {
			content: "";
			position: absolute;
			top: -18rpx;
			left: 10rpx;
			border-width: 0 20rpx 20rpx;
			border-style: solid;
			border-color: transparent transparent #fff;
		}

		.top-end:after {
			content: "";
			position: absolute;
			top: -18rpx;
			right: 10rpx;
			border-width: 0 20rpx 20rpx;
			border-style: solid;
			border-color: transparent transparent #fff;
		}

		.bottom-start:after {
			content: "";
			position: absolute;
			bottom: -18rpx;
			left: 10rpx;
			border-width: 20rpx 20rpx 0;
			border-style: solid;
			border-color: #fff transparent transparent;
		}

		.bottom-end:after {
			content: "";
			position: absolute;
			bottom: -18rpx;
			right: 10rpx;
			border-width: 20rpx 20rpx 0;
			border-style: solid;
			border-color: #fff transparent transparent;
		}

		.disabledColor {
			color: #c5c8ce;
		}
	}

	.solid-bottom {
		border-bottom: 1px solid #f3f5f7;
	}

	.solid-right {
		border-right: 1px solid #ccc;
	}

	.popups .itemChild:last-child {
		border: none;
	}
</style>
